#include<iostream>
#include<pthread.h>
#include<assert.h>
#include<queue>
using namespace std;


#define GMAXCAP 5//宏定义阻塞队列的最大容量
template<class T>
class blockqueue
{
    public:
 blockqueue()//构造
 :_maxcap(GMAXCAP)
 {
    pthread_mutex_init(&_mut,nullptr);//初始化互斥锁
    pthread_cond_init(&_pcond,nullptr);//初始化生产者的条件变量
    pthread_cond_init(&_ccond,nullptr);//初始化消费者的条件变量
 }

 void push(T&in)//输入型参数用&
 {
    pthread_mutex_lock(&_mut);//加锁
    while(is_full())
    {
        pthread_cond_wait(&_pcond,&_mut);//若队列为满，生产者需要阻塞等待，直到队列不为满才能放数据
    }
//走到这就放数据
_q.push(in);//往队列中放数据
pthread_mutex_unlock(&_mut);//解锁
pthread_cond_signal(&_ccond);//唤醒消费者线程
 }

 void pop(T* out)//输出型参数用*。输入输出型参数用&
{
pthread_mutex_lock(&_mut);//加锁
while(is_empty())//队列为空消费者就需要阻塞等待，直到队列中至少存在一个数据
{
    pthread_cond_wait(&_ccond,&_mut);
}
//走到这可以取数据
*out=_q.front();
_q.pop();
pthread_mutex_unlock(&_mut);//解锁
pthread_cond_signal(&_pcond);//唤醒生产者线程
}

~blockqueue()
{
pthread_mutex_destroy(&_mut);//释放互斥锁
pthread_cond_destroy(&_pcond);//释放生产者条件变量
pthread_cond_destroy(&_ccond);//释放消费者生产变量
}
bool is_full()
{
    return _q.size()==_maxcap;//判断队列是否为满
}

bool is_empty()
{
    return _q.size()==0;//判断队列是否为空
}


private:
queue<T> _q;//队列
int _maxcap;//队列中的最大容量
pthread_mutex_t _mut;//互斥锁
pthread_cond_t _pcond;//生产者的条件变量
pthread_cond_t _ccond;//消费者的条件变量
};